From 8b0e7ae03e84fe279d049c1221dd4f3e389191ab Mon Sep 17 00:00:00 2001 From: oliskoli Date: Tue, 13 Jun 2006 21:48:11 +0000 Subject: [PATCH] Add new function xasprintf for 'buffer-free' printf and alloc (as asprintf, which is not C89 conform). Split 'init_date_and_time_format' from garmin_txt into 'convert_human_date_format' and 'convert_human_time_format'. --- defs.h | 3 + util.c | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) diff --git a/defs.h b/defs.h index 727f48d12..4a0aff699 100644 --- a/defs.h +++ b/defs.h @@ -660,6 +660,7 @@ char *gstrsub(const char *s, const char *search, const char *replace); char *xstrrstr(const char *s1, const char *s2); void rtrim(char *s); char * lrtrim(char *s); +int xasprintf(char **strp, const char *fmt, ...); signed int get_tz_offset(void); time_t mkgmtime(struct tm *t); time_t current_time(void); @@ -671,6 +672,8 @@ char * xml_entitize(const char * str); char * html_entitize(const char * str); char * strip_html(const utf_string*); char * strip_nastyhtml(const char * in); +char * convert_human_date_format(const char *human_datef); /* "MM,YYYY,DD" -> "%m,%Y,%d" */ +char * convert_human_time_format(const char *human_timef); /* "HH+mm+ss" -> "%H+%M+%S" */ /* * Character encoding transformations. diff --git a/util.c b/util.c index a728e0008..080b555e2 100644 --- a/util.c +++ b/util.c @@ -24,6 +24,7 @@ #include #include #include +#include static int i_am_little_endian = -1; static int doswap(void); @@ -281,6 +282,30 @@ xfputs(const char *errtxt, const char *s, FILE *stream) } } +/* + * Allocate a string using a format list with optional arguments + */ + +int +xasprintf(char **strp, const char *fmt, ...) +{ + va_list args; + int res; + + va_start(args, fmt); + res = vsnprintf((char *)NULL, 0, fmt, args); + *strp = xmalloc(res + 1); + va_end(args); + + va_start(args, fmt); + res = vsnprintf(*strp, res + 1, fmt, args); + va_end(args); + + is_fatal(res < 0, "(internal): vsnprintf returned %d!", res); + + return res; +} + /* * Duplicate a pascal string into a normal C string. */ @@ -905,6 +930,165 @@ rot13( const char *s ) return result; } +/* + * Convert a human readable date format (i.e. "YYYY/MM/DD") into + * a format usable for strftime and others + */ + +char * +convert_human_date_format(const char *human_datef) +{ + char *result, *cin, *cout; + char prev; + int ylen; + + result = xcalloc((2*strlen(human_datef)) + 1, 1); + cout = result; + prev = '\0'; + ylen = 0; + + for (cin = (char *)human_datef; *cin; cin++) + { + char okay = 1; + + if (toupper(*cin) != 'Y') ylen = 0; + if (isalpha(*cin)) + { + switch(*cin) + { + case 'y': case 'Y': + if (prev != 'Y') + { + strcat(cout, "%y"); + cout += 2; + prev = 'Y'; + } + ylen++; + if (ylen > 2) *(cout-1) = 'Y'; + break; + case 'm': case 'M': + if (prev != 'M') + { + strcat(cout, "%m"); + cout += 2; + prev = 'M'; + } + break; + case 'd': case 'D': + if (prev != 'D') + { + strcat(cout, "%d"); + cout += 2; + prev = 'D'; + } + break; + default: + okay = 0; + } + } + else if (ispunct(*cin)) + { + *cout++ = *cin; + prev = '\0'; + } + else okay = 0; + + is_fatal(okay == 0, "Invalid character \"%c\" in date format!", *cin); + } + return result; +} + +/* + * Convert a human readable time format (i.e. "HH:mm:ss") into + * a format usable for strftime and others + */ + +char * +convert_human_time_format(const char *human_timef) +{ + char *result, *cin, *cout; + char prev; + + result = xcalloc((2*strlen(human_timef)) + 1, 1); + cout = result; + prev = '\0'; + + for (cin = (char *)human_timef; *cin; cin++) + { + int okay = 1; + + if (isalpha(*cin)) + { + switch(*cin) + { + case 'S': case 's': + if (prev != 'S') { + strcat(cout, "%S"); + cout += 2; + prev = 'S'; + } + break; + + case 'M': case 'm': + if (prev != 'M') { + strcat(cout, "%M"); + cout += 2; + prev = 'M'; + } + break; + + case 'h': /* 12-hour-clock */ + if (prev != 'H') { + strcat(cout, "%l"); /* 1 .. 12 */ + cout += 2; + prev = 'H'; + } + else *(cout-1) = 'I'; /* 01 .. 12 */ + break; + + case 'H': /* 24-hour-clock */ + if (prev != 'H') { + strcat(cout, "%k"); + cout += 2; + prev = 'H'; + } + else *(cout-1) = 'H'; + break; + + case 'x': + if (prev != 'X') { + strcat(cout, "%P"); + cout += 2; + prev = 'X'; + } + else *(cout-1) = 'P'; + break; + + case 'X': + if (prev != 'X') { + strcat(cout, "%p"); + cout += 2; + prev = 'X'; + } + else *(cout-1) = 'p'; + break; + + default: + okay = 0; + } + } + else if (ispunct(*cin) || isspace(*cin)) + { + *cout++ = *cin; + prev = '\0'; + } + else okay = 0; + + is_fatal(okay == 0, "Invalid character \"%c\" in time format!", *cin); + } + return result; +} + /* * Get rid of potentially nasty HTML that would influence another record * that includes; -- 2.30.2